package com.cloudweb.oa.controller;

import cn.js.fan.db.ListResult;
import cn.js.fan.util.ErrMsgException;
import cn.js.fan.util.ParamUtil;
import cn.js.fan.util.ResKeyException;
import cn.js.fan.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cloudweb.oa.entity.Department;
import com.cloudweb.oa.security.AuthUtil;
import com.cloudweb.oa.service.IDepartmentService;
import com.cloudweb.oa.utils.I18nUtil;
import com.cloudweb.oa.utils.ResponseUtil;
import com.cloudweb.oa.vo.Result;
import com.cloudwebsoft.framework.util.LogUtil;
import com.redmoon.dingding.service.department.DepartmentService;
import com.redmoon.oa.dept.DeptDb;
import com.redmoon.oa.dept.DeptView;
import com.redmoon.oa.flow.*;
import com.redmoon.oa.person.UserMgr;
import com.redmoon.oa.pvg.Privilege;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

@Controller
public class PaperController {
    @Autowired
    ResponseUtil responseUtil;

    @Autowired
    HttpServletRequest request;

    @Autowired
    IDepartmentService departmentService;

    @Autowired
    I18nUtil i18nUtil;

    @Autowired
    AuthUtil authUtil;

    @ResponseBody
    @RequestMapping(value = "/paper/setReceiveRole", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;charset=UTF-8;"})
    public String setReceiveRole(@RequestParam(value = "swRoles") String swRoles) throws ErrMsgException {
        PaperConfig pc = PaperConfig.getInstance();
        pc.setProperty("swRoles", swRoles);
        PaperConfig.reload();
        return responseUtil.getResJson(true).toString();
    }

    @ApiOperation(value = "公文模板列表", notes = "公文模板列表", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "年份", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "年份", required = true, dataType = "Integer"),
    })
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin', 'admin.unit')")
    @ResponseBody
    @RequestMapping(value = "/paper/list", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;charset=UTF-8;"})
    public Result<Object> list(@RequestParam(value = "page", required = false, defaultValue = "1") Integer page, @RequestParam(value = "pageSize", required = false, defaultValue = "20") Integer pageSize) {
        Privilege privilege = new Privilege();
        String myUnitCode = privilege.getUserUnitCode(request);

        String action = ParamUtil.get(request, "action");
        String title = ParamUtil.get(request, "title");

        String sql;

        DocTemplateDb ld = new DocTemplateDb();
        if ("search".equals(action) && !"".equals(title)) {
            sql = "select id from " + ld.getTableName() + " where title like " + StrUtil.sqlstr("%" + title + "%") + " and unit_code=" + StrUtil.sqlstr(myUnitCode) + " order by sort asc";
            if (myUnitCode.equals(DeptDb.ROOTCODE)) {
                sql = "select id from " + ld.getTableName() + " where title like " + StrUtil.sqlstr("%" + title + "%") + " order by unit_code asc, sort asc";
            }
        } else {
            sql = "select id from " + ld.getTableName() + " where unit_code=" + StrUtil.sqlstr(myUnitCode) + " order by sort asc";
            if (myUnitCode.equals(DeptDb.ROOTCODE)) {
                sql = "select id from " + ld.getTableName() + " order by unit_code asc, sort asc";
            }
        }
        // System.out.println(getClass() + " sql=" +sql);

        JSONArray arr = new JSONArray();
        DeptDb dd = new DeptDb();
        ListResult lr = ld.listResult(sql, page, pageSize);
        long total = lr.getTotal();
        Vector v = lr.getResult();
        for (Object o : v) {
            ld = (DocTemplateDb) o;

            String depts = ld.getDepts();
            String deptNames = "";
            String[] ary = StrUtil.split(depts, ",");
            if (ary != null) {
                for (String s : ary) {
                    if ("".equals(deptNames)) {
                        deptNames = dd.getDeptDb(s).getName();
                    } else {
                        deptNames += "," + dd.getDeptDb(s).getName();
                    }
                }
            }

            String typeCodes = ld.getTypeCodes();
            String typeNames = "";
            ary = StrUtil.split(typeCodes, ",");
            if (ary != null) {
                Leaf lf = new Leaf();
                for (String s : ary) {
                    lf = lf.getLeaf(s);
                    if (lf == null) {
                        LogUtil.getLog(getClass()).warn("Flow typeCode: " + s + " is not exist.");
                        continue;
                    }
                    if ("".equals(typeNames)) {
                        typeNames = lf.getName();
                    } else {
                        typeNames += "," + lf.getName();
                    }
                }
            }

            JSONObject json = new JSONObject();
            json.put("depts", depts);
            json.put("deptNames", deptNames);
            json.put("typeCodes", typeCodes);
            json.put("typeNames", typeNames);
            json.put("id", ld.getId());
            json.put("title", ld.getTitle());
            json.put("sort", ld.getSort());
            json.put("unitCode", ld.getUnitCode());
            json.put("unitName", ld.getUnitCode().equals(Leaf.UNIT_CODE_PUBLIC) ? "公共模板" : dd.getDeptDb(ld.getUnitCode()).getName());
            json.put("hasTail", !StrUtil.isEmpty(ld.getFileNameTail()));
            arr.add(json);
        }

        JSONObject json = new JSONObject();
        json.put("total", total);
        json.put("list", arr);
        return new Result<>(json);
    }

    @ApiOperation(value = "获取单位树形结构", notes = "获取单位树形结构", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @ResponseBody
    @RequestMapping(value = "/paper/getUnitTree", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;charset=UTF-8;"})
    public Result<Object> getUnitTree() {
        Privilege privilege = new Privilege();
        String myUnitCode = privilege.getUserUnitCode(request);
        List<Department> list;
        if (myUnitCode.equals(DeptDb.ROOTCODE)) {
            list = departmentService.getDepartmentsByUnitCode(myUnitCode);
        } else {
            list = new ArrayList<>();
            list.add(departmentService.getDepartment(myUnitCode));
        }
        return new Result<>(list);
    }

    @ApiOperation(value = "创建模板", notes = "创建模板", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin', 'admin.unit')")
    @ResponseBody
    @RequestMapping(value = "/paper/create", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;charset=UTF-8;"})
    public Result<Object> create() {
        boolean re;
        try {
            DocTemplateMgr lm = new DocTemplateMgr();
            ServletContext application = request.getSession().getServletContext();
            re = lm.add(application, request);
        } catch (ErrMsgException e) {
            return new Result<>(false, e.getMessage());
        }
        return new Result<>(re);
    }

    @ApiOperation(value = "修改模板", notes = "修改模板", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin', 'admin.unit')")
    @ResponseBody
    @RequestMapping(value = "/paper/update", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;charset=UTF-8;"})
    public Result<Object> update() {
        boolean re;
        try {
            DocTemplateMgr lm = new DocTemplateMgr();
            ServletContext application = request.getSession().getServletContext();
            re = lm.modify(application, request);
        } catch (ErrMsgException e) {
            return new Result<>(false, e.getMessage());
        }
        return new Result<>(re);
    }

    @ApiOperation(value = "删除模板", notes = "删除模板", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin', 'admin.unit')")
    @ResponseBody
    @RequestMapping(value = "/paper/del", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;charset=UTF-8;"})
    public Result<Object> del() {
        boolean re;
        try {
            DocTemplateMgr lm = new DocTemplateMgr();
            ServletContext application = request.getSession().getServletContext();
            re = lm.del(application, request);
        } catch (ErrMsgException e) {
            return new Result<>(false, e.getMessage());
        }
        return new Result<>(re);
    }

    @ApiOperation(value = "列出文号", notes = "列出文号", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin', 'admin.unit')")
    @ResponseBody
    @RequestMapping(value = "/paper/listPaperNo", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;charset=UTF-8;"})
    public Result<Object> listPaperNo(@RequestParam(value = "page", defaultValue = "1") Integer page, @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
        String myUnitCode = authUtil.getUserUnitCode();

        String action = ParamUtil.get(request, "action");
        String what = ParamUtil.get(request, "what");
        PaperNoPrefixDb pnpd = new PaperNoPrefixDb();

        String sql;
        if ("search".equals(action) && !"".equals(what)) {
            sql = "select id from " + pnpd.getTable().getName() + " where name like " + StrUtil.sqlstr("%" + what + "%") + " and unit_code=" + StrUtil.sqlstr(myUnitCode) + " order by orders desc";
            if (myUnitCode.equals(DeptDb.ROOTCODE)) {
                sql = "select id from " + pnpd.getTable().getName() + " where name like " + StrUtil.sqlstr("%" + what + "%") + " order by unit_code asc, orders desc";
            }
        } else {
            sql = "select id from " + pnpd.getTable().getName() + " where unit_code=" + StrUtil.sqlstr(myUnitCode) + " order by orders desc";
            if (myUnitCode.equals(DeptDb.ROOTCODE)) {
                sql = "select id from " + pnpd.getTable().getName() + " order by unit_code asc, orders desc";
            }
        }

        ListResult lr;
        try {
            lr = pnpd.listResult(sql, page, pageSize);
        } catch (ResKeyException e) {
            return new Result<>(false, e.getMessage(request));
        }

        JSONArray ary = new JSONArray();
        Iterator ir = lr.getResult().iterator();
        DeptDb dd = new DeptDb();
        PaperNoPrefixDeptDb pnpdd = new PaperNoPrefixDeptDb();
        while (ir.hasNext()) {
            pnpd = (PaperNoPrefixDb) ir.next();

            long id = pnpd.getLong("id");
            String name = pnpd.getString("name");
            int orders = pnpd.getInt("orders");

            String depts = "";
            String deptNames = "";
            for (DeptDb deptDb : pnpdd.getDepts(id)) {
                dd = deptDb;
                if ("".equals(deptNames)) {
                    depts = dd.getCode();
                    deptNames = dd.getName();
                } else {
                    depts += "," + dd.getCode();
                    deptNames += "," + dd.getName();
                }
            }

            JSONObject json = new JSONObject();
            json.put("id", pnpd.getInt("id"));
            json.put("name", name);
            json.put("sort", orders);
            json.put("depts", depts);
            json.put("deptNames", deptNames);
            dd = dd.getDeptDb(pnpd.getString("unit_code"));
            json.put("unitName", dd.getName());
            json.put("unitCode", pnpd.getString("unit_code"));
            ary.add(json);
        }
        return new Result<>(ary);
    }

    @ApiOperation(value = "添加文号", notes = "添加文号", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin', 'admin.unit')")
    @ResponseBody
    @RequestMapping(value = "/paper/createPaperNo", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;charset=UTF-8;"})
    public Result<Object> createPaperNo() {
        PaperNoPrefixMgr pp = new PaperNoPrefixMgr();
        boolean re;
        try {
            re = pp.create(request);
        } catch (ResKeyException e) {
            return new Result<>(false, e.getMessage(request));
        }
        return new Result<>(re);
    }

    @ApiOperation(value = "修改文号", notes = "修改文号", httpMethod = "POST")
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin', 'admin.unit')")
    @ResponseBody
    @RequestMapping(value = "/paper/updatePaperNo", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;charset=UTF-8;"})
    public Result<Object> updatePaperNo() {
        boolean re;
        PaperNoPrefixMgr pp = new PaperNoPrefixMgr();
        try {
            re = pp.save(request);
        } catch (ResKeyException e) {
            return new Result<>(false, e.getMessage(request));
        } catch (ErrMsgException | SQLException e) {
            return new Result<>(false, e.getMessage());
        }
        return new Result<>(re);
    }

    @ApiOperation(value = "删除文号", notes = "删除文号", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "Integer"),
    })
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin', 'admin.unit')")
    @ResponseBody
    @RequestMapping(value = "/paper/delPaperNo", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;charset=UTF-8;"})
    public Result<Object> delPaperNo() {
        PaperNoPrefixMgr pp = new PaperNoPrefixMgr();
        return new Result<>(pp.del(request));
    }

    @ApiOperation(value = "列出文号值", notes = "列出文号值", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "prefixId", value = "文号ID", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "page", value = "页码", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, dataType = "Integer"),
    })
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin', 'admin.unit')")
    @ResponseBody
    @RequestMapping(value = "/paper/listPaperNoValue", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;charset=UTF-8;"})
    public Result<Object> listPaperNoValue(@RequestParam Integer prefixId, @RequestParam(value = "page", defaultValue = "1") Integer page, @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
        JSONObject json = new JSONObject();
        PaperNoDb pdd = new PaperNoDb();
        JSONArray ary = new JSONArray();
        String sql = "select id from " + pdd.getTable().getName() + " where prefix_id=" + prefixId;
        ListResult lr = null;
        try {
            lr = pdd.listResult(sql, page, pageSize);
            Vector v = lr.getResult();
            for (Object o : v) {
                pdd = (PaperNoDb) o;
                long id = pdd.getLong("id");
                int curNum = pdd.getInt("cur_num");
                int curYear = pdd.getInt("cur_year");
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("id", id);
                jsonObject.put("curNum", curNum);
                jsonObject.put("curYear", curYear);
                ary.add(jsonObject);
            }
        } catch (ResKeyException e) {
            return new Result<>(false, e.getMessage());
        }
        json.put("total", lr.getTotal());
        json.put("list", ary);
        return new Result<>(json);
    }

    @ApiOperation(value = "保存文号值", notes = "保存文号值", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "Integer"),
            @ApiImplicitParam(name = "curNum", value = "值", required = true, dataType = "Integer"),
    })
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin', 'admin.unit')")
    @ResponseBody
    @RequestMapping(value = "/paper/updatePaperNoValue", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;charset=UTF-8;"})
    public Result<Object> updatePaperNoValue(@RequestParam Integer id, @RequestParam Integer curNum) {
        boolean re;
        try {
            PaperNoDb pdd = new PaperNoDb();
            pdd = pdd.getPaperNoDb(id);
            pdd.set("cur_num", curNum);
            re = pdd.save();
        } catch (ResKeyException e) {
            return new Result<>(false, e.getMessage());
        }
        return new Result<>(re);
    }

    @ApiOperation(value = "删除文号值", notes = "删除文号值", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "ID", required = true, dataType = "Integer"),
    })
    @ApiResponses({@ApiResponse(code = 200, message = "操作成功")})
    @PreAuthorize("hasAnyAuthority('admin', 'admin.unit')")
    @ResponseBody
    @RequestMapping(value = "/paper/delPaperNoValue", method = RequestMethod.POST, produces = {"text/html;charset=UTF-8;", "application/json;charset=UTF-8;"})
    public Result<Object> delPaperNoValue(@RequestParam Integer id) {
        boolean re;
        try {
            PaperNoDb pdd = new PaperNoDb();
            pdd = pdd.getPaperNoDb(id);
            re = pdd.del();
        } catch (ResKeyException e) {
            return new Result<>(false, e.getMessage());
        }
        return new Result<>(re);
    }
}
